<template>
    <div class="range-number-input">
      <!-- 前置内容 -->
      <div v-if="$slots.prepend" class="range-input-prepend">
        <slot name="prepend"></slot>
      </div>
  
      <!-- 范围输入框 -->
      <div class="range-inputs">
        <el-input-number
          ref="minInputRef"
          v-model="minValue"
          :min="minLimit"
          :max="maxValue"
          :step="step"
          :precision="precision"
          :disabled="disabled"
          :controls="controls"
          :controls-position="controlsPosition"
          :placeholder="minPlaceholder"
          :size="size"
          @change="handleMinChange"
          @blur="handleBlur('min')"
          class="range-input"
        />
        
        <span class="range-separator">{{ separator }}</span>
        
        <el-input-number
          ref="maxInputRef"
          v-model="maxValue"
          :min="minValue"
          :max="maxLimit"
          :step="step"
          :precision="precision"
          :disabled="disabled"
          :controls="controls"
          :controls-position="controlsPosition"
          :placeholder="maxPlaceholder"
          :size="size"
          @change="handleMaxChange"
          @blur="handleBlur('max')"
          class="range-input"
        />
      </div>
  
      <!-- 后置内容 -->
      <div v-if="$slots.append" class="range-input-append">
        <slot name="append"></slot>
      </div>
  
      <!-- 单位显示 -->
      <span v-if="unit" class="range-unit">{{ unit }}</span>
    </div>
  </template>
  
  <script setup>
  import { ref, watch, computed, nextTick } from 'vue'
  
  // 定义 Props
  const props = defineProps({
    modelValue: {
      type: Object,
      default: () => ({ min: null, max: null })
    },
    min: {
      type: Number,
      default: null
    },
    max: {
      type: Number,
      default: null
    },
    minLimit: {
      type: Number,
      default: -Infinity
    },
    maxLimit: {
      type: Number,
      default: Infinity
    },
    step: {
      type: Number,
      default: 1
    },
    precision: {
      type: Number,
      default: 0
    },
    separator: {
      type: String,
      default: '-'
    },
    unit: {
      type: String,
      default: ''
    },
    disabled: {
      type: Boolean,
      default: false
    },
    controls: {
      type: Boolean,
      default: true
    },
    controlsPosition: {
      type: String,
      default: '',
      validator: (value) => ['', 'right'].includes(value)
    },
    minPlaceholder: {
      type: String,
      default: '最小值'
    },
    maxPlaceholder: {
      type: String,
      default: '最大值'
    },
    size: {
      type: String,
      default: 'default',
      validator: (value) => ['large', 'default', 'small'].includes(value)
    },
    // 是否自动交换大小值
    autoSwap: {
      type: Boolean,
      default: true
    },
    // 是否在 blur 时触发验证
    validateOnBlur: {
      type: Boolean,
      default: true
    }
  })
  
  // 定义 Emits
  const emit = defineEmits(['update:modelValue', 'update:min', 'update:max', 'change', 'blur', 'validate-error'])
  
  // 响应式数据
  const minValue = ref(props.min ?? props.modelValue.min)
  const maxValue = ref(props.max ?? props.modelValue.max)
  const minInputRef = ref(null)
  const maxInputRef = ref(null)
  
  // 计算属性 - 用于 v-model 绑定
  const rangeValue = computed(() => ({
    min: minValue.value,
    max: maxValue.value
  }))
  
  // 监听器 - 处理外部传入的 min/max 变化
  watch(() => props.min, (newVal) => {
    if (newVal !== minValue.value) {
      minValue.value = newVal
    }
  })
  
  watch(() => props.max, (newVal) => {
    if (newVal !== maxValue.value) {
      maxValue.value = newVal
    }
  })
  
  // 监听器 - 处理内部值变化并触发事件
  watch(rangeValue, (newVal) => {
    emit('update:modelValue', newVal)
    emit('update:min', newVal.min)
    emit('update:max', newVal.max)
    emit('change', newVal)
  }, { deep: true })
  
  // 最小值变化处理
  const handleMinChange = (value) => {
    if (value === null || value === undefined) return
    
    // 如果最小值大于最大值且允许自动交换
    if (props.autoSwap && value > maxValue.value) {
      const temp = maxValue.value
      maxValue.value = value
      minValue.value = temp
      nextTick(() => {
        emit('validate-error', {
          type: 'swapped',
          message: '最小值不能大于最大值，已自动交换'
        })
      })
    }
  }
  
  // 最大值变化处理
  const handleMaxChange = (value) => {
    if (value === null || value === undefined) return
    
    // 如果最大值小于最小值且允许自动交换
    if (props.autoSwap && value < minValue.value) {
      const temp = minValue.value
      minValue.value = value
      maxValue.value = temp
      nextTick(() => {
        emit('validate-error', {
          type: 'swapped',
          message: '最大值不能小于最小值，已自动交换'
        })
      })
    }
  }
  
  // 失焦处理
  const handleBlur = (type) => {
    emit('blur', { type, value: rangeValue.value })
    
    if (props.validateOnBlur) {
      validateRange()
    }
  }
  
  // 范围验证
  const validateRange = () => {
    const errors = []
    
    if (minValue.value !== null && minValue.value < props.minLimit) {
      errors.push(`最小值不能小于 ${props.minLimit}`)
    }
    
    if (maxValue.value !== null && maxValue.value > props.maxLimit) {
      errors.push(`最大值不能大于 ${props.maxLimit}`)
    }
    
    if (minValue.value !== null && maxValue.value !== null && minValue.value > maxValue.value) {
      errors.push('最小值不能大于最大值')
    }
    
    if (errors.length > 0) {
      emit('validate-error', {
        type: 'validation',
        errors: errors
      })
      return false
    }
    
    return true
  }
  
  // 公开的方法
  const focus = () => {
    minInputRef.value?.focus()
  }
  
  const blur = () => {
    minInputRef.value?.blur()
    maxInputRef.value?.blur()
  }
  
  const reset = () => {
    minValue.value = null
    maxValue.value = null
  }
  
  // 暴露给模板的方法和属性
  defineExpose({
    focus,
    blur,
    reset,
    validate: validateRange,
    minValue,
    maxValue
  })
  </script>
  
  <style scoped>
  .range-number-input {
    display: inline-flex;
    align-items: center;
    gap: 8px;
  }
  
  .range-inputs {
    display: inline-flex;
    align-items: center;
  }
  
  .range-input {
    width: 120px;
  }
  
  .range-separator {
    margin: 0 8px;
    color: var(--el-text-color-regular);
    font-size: 14px;
  }
  
  .range-unit {
    margin-left: 4px;
    color: var(--el-text-color-secondary);
    font-size: 14px;
  }
  
  .range-input-prepend,
  .range-input-append {
    display: inline-flex;
    align-items: center;
  }
  
  /* 响应式设计 */
  @media (max-width: 768px) {
    .range-number-input {
      flex-direction: column;
      align-items: stretch;
      gap: 8px;
    }
    
    .range-inputs {
      justify-content: space-between;
    }
    
    .range-input {
      flex: 1;
    }
  }
  </style>